import { computed, defineComponent, nextTick, ref, withModifiers ,watch} from 'vue';

import { useFormChild, useQuasar } from '@teld/q-components';
import Component from '@teld/q-components/Editor';
import QButton from '@teld/q-components/Button';
import QButtonDropdown from '@teld/q-components/ButtonDropdown';
import QColor from '@teld/q-components/Color';
import { QList, QItem, QItemSection } from '@teld/q-components/Item';
import TIcon from 't/basic/icon';
import useMappingProps from 't/common/hooks/useMappingProps';
import {
  commonProps,
  fixNameSpace,
  pickOwnForBasicComponent,
} from 't/common/utils';
import LabelPrefixWraper from '../label-prefix-wraper';
import styles from './index.module.scss';
import './index.scss';
import CreateImgEntities from './create-img.entities';
import imgSetPanel from './img-set-panel';
import colorSetPanel from './color-set-panel';
import base64ToUrl from './base64ToUrl';

export * from '@teld/q-components/Editor';

import TInnerLoading from 't/basic/inner-loading';

import {
  readAsBase64,
  isSupportedImageType,
} from 't/bussiness/comment/hooks';
import { apiUploadFile } from 't/bussiness/comment/hooks/api';

export default defineComponent({
  name: fixNameSpace(Component.name),

  props: {
    ...commonProps,
    ...Component.props,
    ...LabelPrefixWraper.props,
    modelValue: {
      type: String,
      default() {
        return '';
      },
    },
    label: {
      type: String,
      default() {
        return '';
      },
    },
    labelPosition: {
      type: String,
      default() {
        return 'top';
      },
    },
    // 是否简洁模式
    isSimple: {
      type: Boolean,
      default: false,
    },
    // 必填校验相关
    required: {
      type: Boolean,
      default() {
        return false;
      },
    },
    dense: {
      type: Boolean,
      default() {
        return false;
      },
    },
    maxLength: {
      type: Number,
      default: 0,
    },
    maxLengthMsg: {
      type: String,
      default() {
        return Funcs.GetTerms(
          'Schema.Controls.fasr_editor.Terms.characterIsExceeded',
          '超出字符限制，最大允许${value}字符',
        );
      },
    },
    requiredMessage: {
      type: String,
      default() {
        return '';
      },
    },
    tabIndex: {
      type: [String, Number],
      default() {
        return '1';
      },
    },
    selectedToolbar:Array,
    customizeToolbar: Boolean,
    pasteImage2Res: {
      type: Boolean,
      default() {
        return false;
      },
    },
  },

  emits: ['update:modelValue', 'change', 'click', 'blur', 'focus'],

  setup(props, { attrs, emit, expose, slots }) {
    const $q = useQuasar();
    // $q.screen.setSizes({ sm: 391, md: 769, lg: 993, xl: 1201 });
    const isMobile = computed(
      () =>
        // $q.screen.lg ||
        //  $q.screen.md ||
        $q.screen.xs || $q.platform.is.mobile,
    );

    const isFocused = ref(false);
    const refComponent = ref();
    let filteredTextStyles = [];
    let filteredEditorToolbarConfig = [];
    let filteredParagraphControls = [];
    let filteredEditorFeatures = [];
    const [mappingProps, mappingExpose] = useMappingProps(props);

    const focusedClass = computed(() =>
      isFocused.value ? 'q-editor--focused' : '',
    );

    let textStyles = {
      bold: 'bold',
      italic: 'italic',
      strike: 'strike',
      underline: 'underline',
      subscript: 'subscript',
      superscript: 'superscript',
      align: {
        label: $q.lang.editor.align,
        icon: $q.iconSet.editor.align,
        fixedLabel: true,
        options: ['left', 'center', 'right', 'justify'],
      },
    };

    let editorToolbarConfig = {
     formatting:{
        label: $q.lang.editor.formatting,
        icon: $q.iconSet.editor.formatting,
        list: 'no-icons',
        options: ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'code'],
      },
     fontSize: {
        label: $q.lang.editor.fontSize,
        icon: $q.iconSet.editor.fontSize,
        fixedLabel: true,
        fixedIcon: true,
        list: 'no-icons',
        options: [
          'size-1',
          'size-2',
          'size-3',
          'size-4',
          'size-5',
          'size-6',
          'size-7',
        ],
      },
      removeFormat:'removeFormat',
    };

    let editorFeatures = {
      token: 'token',
      hr: 'hr',
      link: 'link',
      create_img: 'create_img'
    };

   let paragraphControls = {
     quote: 'quote',
     unordered: 'unordered',
     ordered:'ordered',
     outdent: 'outdent',
     indent: 'indent',
     fullscreen: 'fullscreen'
   };
        function filterToolbarOptions(selectedToolbar, configObject) {
          return _.transform(
            selectedToolbar,
            (result, item) => {
              const value = item.value;
              if (!item.enable || item.enable === false) {
                return; // 跳过禁用的项
              }
              if (configObject[value]) {
                result.push(configObject[value]);
              }
            },
            [],
          );
        }
    if (mappingProps.selectedToolbar) {
        // 使用通用函数来过滤不同的配置
        filteredTextStyles = filterToolbarOptions(
          mappingProps.selectedToolbar,
          textStyles,
        );
        filteredEditorToolbarConfig = filterToolbarOptions(
          mappingProps.selectedToolbar,
          editorToolbarConfig,
        );
        filteredEditorFeatures = filterToolbarOptions(
          mappingProps.selectedToolbar,
          editorFeatures,
        );
        filteredParagraphControls = filterToolbarOptions(
          mappingProps.selectedToolbar,
          paragraphControls,
        );
      // console.log(filteredTextStyles, 'filteredTextStyles');
      // console.log(filteredEditorToolbarConfig, 'filteredEditorToolbarConfig');
      // console.log(filteredParagraphControls, 'filteredParagraphControls');
    }

    const toolbar = computed(() => {
      //debugger;
      //console.log('toolbar.selectedToolbar', mappingProps.selectedToolbar);
          if (mappingProps.customizeToolbar && mappingProps.customizeToolbar == true) {
            if (
              mappingProps.selectedToolbar &&
              mappingProps.selectedToolbar.length >= 0
            ) {
              var editorToolbarSelected = [
                filterToolbarOptions(mappingProps.selectedToolbar, textStyles),
                filterToolbarOptions(
                  mappingProps.selectedToolbar,
                  editorToolbarConfig,
                ),
                filterToolbarOptions(
                  mappingProps.selectedToolbar,
                  editorFeatures,
                ),
                filterToolbarOptions(
                  mappingProps.selectedToolbar,
                  paragraphControls,
                ),
              ].filter(o => o);
              // var slcccc = [
              //   filteredTextStyles.length === 0
              //     ? undefined
              //     : filteredTextStyles,
              //   filteredEditorToolbarConfig.length === 0
              //     ? undefined
              //     : filteredEditorToolbarConfig,
              //   filteredEditorFeatures.length === 0
              //     ? undefined
              //     : filteredEditorFeatures,
              //   filteredParagraphControls.length === 0
              //     ? undefined
              //     : filteredParagraphControls,
              // ].filter(o => o);
              var filteredSelected = editorToolbarSelected.filter(
                item => item.length > 0,
              );
             // console.log('editorToolbarSelected', editorToolbarSelected);
              return filteredSelected;
            }
      }

      const { readonly, isSimple } = mappingProps;
      if (readonly || isSimple || isMobile.value) {
        //只读，简洁模式，移动端展示部分操作按钮
        return [
          ['left', 'center', 'right', 'justify'],
          ['bold', 'italic', 'strike', 'underline', 'create_img'],
          // ['undo', 'redo'],
          ['fullscreen'],
        ];
      }
      return [
        [
          'bold',
          'italic',
          'strike',
          'underline',
          'subscript',
          'superscript',
          {
            label: $q.lang.editor.align,
            icon: $q.iconSet.editor.align,
            fixedLabel: true,
            options: ['left', 'center', 'right', 'justify'],
          },
        ],
        ['token', 'hr', 'link', 'create_img'],
        [
          {
            label: $q.lang.editor.formatting,
            icon: $q.iconSet.editor.formatting,
            list: 'no-icons',
            options: ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'code'],
          },
          {
            label: $q.lang.editor.fontSize,
            icon: $q.iconSet.editor.fontSize,
            fixedLabel: true,
            fixedIcon: true,
            list: 'no-icons',
            options: [
              'size-1',
              'size-2',
              'size-3',
              'size-4',
              'size-5',
              'size-6',
              'size-7',
            ],
          },
          'removeFormat',
        ],
        ['quote', 'unordered', 'ordered', 'outdent', 'indent', 'fullscreen'],
        // ['undo', 'redo'],
        ['viewsource'],
      ];
    });
    let labelPosition = computed(() => {
      if (isMobile.value) {
        return 'top';
      }
      return mappingProps.labelPosition;
    });

    // ============================= 校验相关 ===========================
    // 是否显示必填校验错误
    const displayedErrorHint = ref(false);
    // 错误提示内容
    const errorHint = ref('');
    // 是否必填错误
    const requiredError = computed(() => {
      const { required, modelValue } = mappingProps;
      return (
        required &&
        (typeof modelValue === 'undefined' ||
          modelValue === null ||
          modelValue === 0 ||
          modelValue === '<b><i><br></i></b>' || //苹果端删不干净，会残留这个<br>
          modelValue === '<i><br></i>' || //苹果端删不干净，会残留这个<br>
          modelValue === '<br>' || //苹果端删不干净，会残留这个<br>
          modelValue === '')
      );
    });
    // 是否超长错误
    const maxLengthError = computed(() => {
      const { maxLength, modelValue } = mappingProps;
      return (
        !requiredError.value && maxLength > 0 && modelValue?.length > maxLength
      );
    });
    // 超长错误提示内容
    const maxLengthErrorHint = computed(() => {
      const { maxLength, maxLengthMsg, modelValue } = mappingProps;
      return maxLengthMsg.replace('${value}', maxLength);
    });
    // 必填校验，不能选0
    function validate() {
      const { requiredMessage } = mappingProps;
      if (requiredError.value) {
        errorHint.value = requiredMessage;
      } else if (maxLengthError.value) {
        errorHint.value = maxLengthErrorHint.value;
      }
      displayedErrorHint.value = requiredError.value || maxLengthError.value;
      return !displayedErrorHint.value;
    }
    // 应该返回一个布尔值（或一个 resolve 布尔值的 Promise）
    function resetValidation() {
      displayedErrorHint.value = false;
    }

    // 与qForm组件通信，校验用户输入是否合法
    useFormChild({
      validate, // 函数；可以是异步的；
      resetValidation, // 可选的函数，可重置验证
      requiresQForm: false, // 如果没有找到父级 QForm，它是否应该报错？
    });

    // ---------------------------- 功能集成：颜色配置相关 ----------------------------------
    const tokenRef = ref(null);
    const backColor = ref('');
    const foreColor = ref('');
    function setColor(cmd, name) {
      const edit = refComponent.value;
      tokenRef.value.hide();
      edit.caret.restore();
      edit.runCmd(cmd, name);
      // edit.focus();
    }
    function setBackColor() {
      if (mappingProps.disable || mappingProps.readonly) return;
      setColor('backColor', backColor.value);
    }
    function setForeColor() {
      if (mappingProps.disable || mappingProps.readonly) return;
      setColor('foreColor', foreColor.value);
    }
    // ---------------------------- 功能集成：颜色配置相关 ----------------------------------

    // ---------------------------- 上传图片: start ----------------------------
    function insertHTML(html) {
     // console.log('insertHTML');
      const editor = refComponent.value;
      editor.caret.restore();
      editor.runCmd('insertHTML', html);
      editor.focus();
    }
    function openCreateImg(isCamera = false) {
      const entities = new CreateImgEntities();
      entities.init(imgBase64 => {
        insertHTML(`<img style="max-width:100%" src="${imgBase64}">`);
      }, isCamera);

      entities.open();
      entities.destory();
    }
    function handleClickImgBtn() {
      if (mappingProps.disable || mappingProps.readonly) return;

      if ($q.platform.is.android) {
        // 安卓设备需要分成拍照和选择图片分别处理
        $q.bottomSheet({
          message: '',
          actions: [
            {
              label: '选择图片',
              img: '',
              id: 'pick',
            },
            {
              label: '拍照',
              img: '',
              id: 'camera',
            },
          ],
        }).onOk(action => {
          // console.log('Action chosen:', action.id)
          if (action.id == 'camera') {
            openCreateImg(true);
          } else {
            openCreateImg(false);
          }
        });
      } else {
        openCreateImg();
      }
    }
    // ---------------------------- 上传图片: end ----------------------------
    const imgSetPanelRef = ref(null);
    // 点击富文本里的图片
    async function handleClickImg(params) {
      // 手机上屏蔽该功能
      if (isMobile.value) return;
      // 聚焦
      focusImg(params);
      const { type, data } = await imgSetPanelRef.value.show(
        params?.target,
        params?.target?.src,
        params?.target?.style?.width,
        params?.target?.style?.height,
      );
    //  console.log('confirm', type);

      blurImg(params);
      if (type == 'confirm') {
        const { width, height, src } = data;
        setImgWidth(params, src, width, height);
      }
    }

    // 设置图片
    function setImgWidth(params, src, width = '', height = '') {
      params.target.src = src;
      params.target.style.width = width;
      params.target.style.height = height;

      insertHTML('');
    }
    // 聚焦图片样式添加
    function focusImg(params) {
      params.target.dataSelection = true;
      params.target.style.outline = '4px solid rgba(250, 220, 20, 0.9)';
    }
    // 取消聚焦图片样式添加
    function blurImg(params) {
      params.target.dataSelection = false;
      params.target.style.outline = 'none';
    }

    function watchBigImg(base64String) {
      const url = base64ToUrl(base64String);
      if (url) window.open(url, '_blank');
    }

    function onDoubleClickHandler(params) {
      // console.log('doubleClick', params);
      emit('doubleClick', params);

      // 图片的处理
      if (params?.target && params?.target?.nodeName === 'IMG') {
        // 替代方案被驳回了，暂时先注释掉
        watchBigImg(params?.target?.src || '');
      }
    }

    const isDoubleClick = (function () {
      let lastTime = 0;
      return function () {
        const nowTime = new Date().getTime();
        const gap = nowTime - lastTime;
        lastTime = nowTime;
        return gap > 50 && gap < 300;
      };
    })();
    let selectTarget = null
    function onClickHandler(params) {
      if (isDoubleClick()) return onDoubleClickHandler(params);
      emit('click', params);
      // 获取目标元素
      const target = params.target;

      // 判断是否点击的是链接
      if (target && target.nodeName === 'A') {
        const isCtrlClick = params.ctrlKey || params.metaKey; // 同时支持Windows的Ctrl和Mac的Command键
        // 如果按下了Ctrl或Command键，单独点击鼠标左键，都在新标签页打开链接
        if (isCtrlClick) {
          window.open(target.href, '_blank');
        } else {
          window.open(target.href, '_blank');
        }
          params.preventDefault();
      }
      hideResizeRect(target);
      // 图片的处理
      if (target && target.nodeName === 'IMG') {
        // 替代方案被驳回了，暂时先注释掉
        // handleClickImg(params);
        showResizeRect(target);
      }
      console.log(params.preventDefault);
      params.preventDefault();
      // else {
      //   hideResizeRect();
      // }
    }

    function showResizeRect(target) {
      selectTarget = target
      target.style.outline = '3px solid #b4d7ff';
      var imgRect = target.getBoundingClientRect();
      var targetWidth = imgRect.width || imgRect.right - imgRect.left;
      var targetHeight = imgRect.height || imgRect.bottom - imgRect.top;
      //依次为上 右 下 左
      let dragIcons = [
        {
          cursor: 'nw-resize',
          x: 'top',
          y: 'left',
        },
        {
          cursor: 'ne-resize',
          x: 'top',
          y: 'right',
        },
        {
          cursor: 'se-resize',
          x: 'right',
          y: 'bottom',
        },
        {
          cursor: 'sw-resize',
          x: 'left',
          y: 'bottom',
        },
      ];
      let parentRect = refComponent.value.caret.el.getBoundingClientRect();
      let editHeader =
        refComponent.value.caret.el.parentNode.getElementsByClassName(
          'q-editor__toolbars-container',
        );
      let headerHeight = editHeader[0].offsetHeight;
      let rect = document.createElement('div');

        rect.style.width = targetWidth + 'px';
        rect.style.height = targetHeight + 'px';
        rect.style.position = 'absolute';
        rect.style.zIndex = 10;
        rect.className = 'resize-box';
        // rect.style.backgroundColor = '#b4d7ff';
        rect.style.top = imgRect.top - parentRect.top + headerHeight+1 + 'px';
        rect.style.left = imgRect.left - parentRect.left + 1+ 'px';
        target.parentNode.appendChild(rect);

      // icon.style.top =
      //       40 +
      //       imgRect.top -
      //       parentRect.top -
      //       parseInt(icon.style.width) / 2 +
      //       'px';
      //     icon.style.left =
      //       imgRect.left -
      //       parentRect.left -
      //       parseInt(icon.style.height) / 2 +
      //       'px';

      for (let i = 0, l = dragIcons.length; i < l; i++) {
        let icon = document.createElement('i');
        icon.id = Math.random().toString(36).substring(7);
        icon.style.display = 'inline-block';
        icon.style.width = '10px';
        icon.style.height = '10px';
        icon.style.position = 'absolute';
        icon.style.zIndex = 10;
        icon.className = 'resize-icon';
        icon.style.cursor = dragIcons[i].cursor;
        icon.style.backgroundColor = '#b4d7ff';

        icon.style[dragIcons[i].x] = -parseInt(icon.style.width) / 2 + 'px';
				icon.style[dragIcons[i].y] = -parseInt(icon.style.height) / 2 + 'px';
				//绑定四个角的拖拽事件
				// this.bindDragEvent(icon, `${dragIcons[i].x}-${dragIcons[i].y}`);
				//插入到矩形

        //绑定四个角的拖拽事件
        // this.bindDragEvent(icon, `${dragIcons[i].x}-${dragIcons[i].y}`);
        //插入到矩形
        rect.appendChild(icon);
        dragFn(icon, rect, target);
      }

    }
    function dragFn(obj, rect, target) {
      // 按下鼠标的操作
      obj.onmousedown = function (ev) {
        var oEv = ev || event;
        //   阻止事件的冒泡
        oEv.stopPropagation();
        // 获取移动前盒子的宽高，边角的鼠标坐标，和距离浏览器边界的距离
        var oldWidth = selectTarget.offsetWidth;
        var oldHeight = selectTarget.offsetHeight;
        var oldX = oEv.clientX;
        var oldY = oEv.clientY;
        var oldLeft = selectTarget.offsetLeft;
        var oldTop = selectTarget.offsetTop;

        let mouseHandler = {
          addEventListener() {
            // debugger;
            document.addEventListener('mousemove', this.onmousemove);
            document.addEventListener('mouseup', this.onmouseup);
          },
          removeEventListener(target) {
            debugger;
            document.removeEventListener('mousemove', this.onmousemove);
            document.removeEventListener('mouseup', this.onmouseup);
            hideResizeRect(target);
            // mappingProps.modelValue = refComponent.value.caret.el.innerHTML;
            const modelValue = refComponent.value.caret.el.innerHTML;
            onChange(modelValue);
            // refComponent.value.caret.save();
          },
        };

        // 鼠标移动事件
        mouseHandler.onmousemove = function (ev) {
          var oEv = ev || event;
          // t top  l  left  r right  b bottom， 依次 tl 上左角
          if (obj.style.cursor == 'nw-resize') {
            //                 代表的横向移动的距离，右为正，左为负
            // 计算移动后盒子的宽 = 移动前盒子的宽度 - （移动后的横向坐标-移动前的横向坐标）
            selectTarget.style.width = oldWidth - (oEv.clientX - oldX) + 'px';
            // 高度同理
            selectTarget.style.height = oldHeight - (oEv.clientY - oldY) + 'px';

            // selectTarget.style.left = oldLeft + (oEv.clientX - oldX) + 'px';
            // selectTarget.style.top = oldTop + (oEv.clientY - oldY) + 'px';
          } else if (obj.style.cursor == 'ne-resize') {
            selectTarget.style.width = oldWidth + (oEv.clientX - oldX) + 'px';
            selectTarget.style.height = oldHeight - (oEv.clientY - oldY) + 'px';
            // selectTarget.style.left = oldLeft + (oEv.clientX - oldX) + 'px';
            // selectTarget.style.bottom = oldTop + (oEv.clientY + oldY) + 'px';
          } else if (obj.style.cursor == 'se-resize') {
            selectTarget.style.width = oldWidth + (oEv.clientX - oldX) + 'px';
            selectTarget.style.height = oldHeight + (oEv.clientY - oldY) + 'px';
            // selectTarget.style.right = oldLeft - (oEv.clientX - oldX) + 'px';
            // selectTarget.style.top = oldTop + (oEv.clientY - oldY) + 'px';
          } else if (obj.style.cursor == 'sw-resize') {
            selectTarget.style.width = oldWidth - (oEv.clientX - oldX) + 'px';
            selectTarget.style.height = oldHeight + (oEv.clientY - oldY) + 'px';
            // selectTarget.style.right = oldLeft - (oEv.clientX - oldX) + 'px';
            // selectTarget.style.bottom = oldTop + (oEv.clientY + oldY) + 'px';
          }
          let parentRect = refComponent.value.caret.el.getBoundingClientRect();
          if (parseInt(selectTarget.style.width) > parentRect.width - 16) {
            selectTarget.style.width = parentRect.width - 16 + 'px';
          }

          rect.style.width = selectTarget.style.width;
          rect.style.height = selectTarget.style.height;
          // 更新rect的位置


          var imgRect = selectTarget.getBoundingClientRect();
          let editHeader =
            refComponent.value.caret.el.parentNode.getElementsByClassName(
              'q-editor__toolbars-container',
            );
          let headerHeight = editHeader[0].offsetHeight;
          rect.style.top =
            imgRect.top - parentRect.top + headerHeight + 1 + 'px';
          rect.style.left = imgRect.left - parentRect.left + 1 + 'px';
          // boundary();
        };
        // 松开鼠标时，移除移动的监听
        mouseHandler.onmouseup = function () {
          mouseHandler.removeEventListener(target);
        };
        mouseHandler.addEventListener();
        // 阻止默认事件
        return false;
      };
    }
    function hideResizeRect(target) {
      selectTarget ? selectTarget.style.outline = 'none' : '';

      let icons = document.getElementsByClassName('resize-box');
       icons = Array.prototype.slice.call(icons, 0);


      // 遍历克隆的节点数组
      icons.forEach(function (node) {
        node.parentNode.removeChild(node);
      });
    }
    function onBlur(params) {
      if (mappingProps.required) validate();
      isFocused.value = false;
      emit('blur', params);
    }
    function onFocus(params) {
      isFocused.value = true;
      emit('focus', params);
    }
    function onChange(val) {
      const { maxLength } = mappingProps;

      if (maxLength > 0 && val.length > maxLength) {
        const { modelValue } = mappingProps;
        Funcs.Notify('', maxLengthErrorHint.value, 'warning');

        // 延时重置，否则不生效
        setTimeout(() => {
          mappingProps.modelValue = modelValue;
          mappingExpose.modelValue.value = modelValue;
          emit('update:modelValue', modelValue);
        }, 10);
      }

      mappingProps.modelValue = val;
      mappingExpose.modelValue.value = val;

      emit('update:modelValue', val);
      emit('change', val);

      // 如果已经报了必填错误，更改时校验下
      setTimeout(() => {
        // 苹果手机下，好像触发不了blur方法，放在这里校验吧
        if (mappingProps.required || mappingProps.maxLength > 0) validate();
      }, 20);
    }
    let attrs_ = { ...attrs };
    delete attrs_['data-uid'];
    delete attrs_['data-tag'];
    delete attrs_['class'];
    delete attrs_['style'];

    function focus() {
      refComponent.value.focus();
    }

    function handleColorBtnKeyDownDown(e) {
      // console.log('============ handleColorBtnKeyDownDown', e);
      if (e.code === 'ArrowDown') focus();
    }

    expose({
      ...mappingExpose,
      validate,
      resetValidation,
      focus,
      insertHTML,
    });

    const mergeAttr = {
      ...attrs_,
      ...pickOwnForBasicComponent(mappingProps, Component.props, attrs),
    };
    delete mergeAttr['tabIndex'];

    const onPaste = async e => {
      debugger;
      const evt = e;
      if (evt.target.nodeName === 'INPUT') return;
      let text, onPasteStripFormattingIEPaste;
      evt.preventDefault();
      evt.stopPropagation();
      const clipboardData = (e.originalEvent || e).clipboardData;
      if (!clipboardData) {
        return;
      }
      if (isImg2ResLoading.value) {
        return;
      }

      const items = clipboardData.items;

      const hasHTML = [...items].find(o => o.type == 'text/html');


      for (let index = 0; index < items.length; index++) {
        const item = items[index];
        console.log('start----------');
        console.log('onPaste-item', item);
        if (item.kind === 'file' && isSupportedImageType(item.type)) {
          e.preventDefault();
          // 粘贴图像
          console.log(`粘贴图像`);
          const file = item.getAsFile();
          handlePasteImage(file);
        } else if (item.kind === 'string') {
          if (hasHTML) {
            if (item.type === 'text/html') {
              // 获取 HTML 内容并清理
              item.getAsString(html => {
                refComponent.value.runCmd('insertHTML', html);
              });
            }
          } else {
            if (item.type === 'text/plain') {
              // 获取纯文本
              item.getAsString(text => {
                refComponent.value.runCmd('insertText', text);
              });
            }
          }
        }
        console.log('end----------\n');
      }
    };

    const qLangComment = computed(() => $q.lang?.comment || {});
    const isImg2ResLoading = ref(false);
    const handlePasteImage = async file => {
      isImg2ResLoading.value = true;
      const [strWithType] = await readAsBase64(file);
      try {
        const res = await apiUploadFile({
          fileName: file.name,
          fileContent: strWithType,
        });
        console.log('PC upload file', res);

        if (!res || res.state !== '1' || !res.data) {
          $q.notify({
            message: qLangComment.value.funcImageUploadFailed(res.errmsg),
            // icon: 'error_outline',
            type: 'negative',
            textColor: 'white',
            position: 'top',
            timeout: 1000,
            attrs: {
              // 为通知的 DOM 本身设置属性:
              'comment-notification': 'negative', // 这是为了做精准选择器调样式用的
            },
          });
          return;
        }

        const { AttachmentUrl } = res.data;
        refComponent.value.runCmd('insertImage', AttachmentUrl);
      } catch (error) {
        // this.$TP.$message.error(`图像上传失败`);
        $q.notify({
          message: qLangComment.value.funcImageUploadFailed(),
          // icon: 'error_outline',
          type: 'negative',
          textColor: 'white',
          position: 'top',
          timeout: 1000,
          attrs: {
            // 为通知的 DOM 本身设置属性:
            'comment-notification': 'negative', // 这是为了做精准选择器调样式用的
          },
        });
        console.log(error);
      } finally {
        isImg2ResLoading.value = false;
      }
    };

    return () => {
      return (
        <div
          class={[
            't-editor_div',
            labelPosition.value == 'top' && 'tr-editor-default-top',
            mappingProps.readonly && 'tr-editor-readonly',
          ]}
          v-show={mappingProps.visible}
          {...attrs}
          tabIndex='-1'
        >
          <LabelPrefixWraper
            required={mappingProps.required}
            label={mappingProps.label}
            labelProps={{ class: 'editor-title' }}
            hideLabel={mappingProps.hideLabel}
            labelPosition={labelPosition.value}
            helpConf={mappingProps.helpConf}
            readonly={mappingProps.readonly}
            helpTooltip={mappingProps.helpTooltip}
            helpPlacement={mappingProps.helpPlacement}
            helpMore={mappingProps.helpMore}
            helpMorePopup={mappingProps.helpMorePopup}
            helpMoreLink={mappingProps.helpMoreLink}
            helpMoreLinkHrefStatic={mappingProps.helpMoreLinkHrefStatic}
            helpMoreLinkHrefExp={mappingProps.helpMoreLinkHrefExp}
          ></LabelPrefixWraper>

          <div style='position:relative; width:100%'>
            <div>
              <Component
                ref={refComponent}
                {...attrs_}
                {...pickOwnForBasicComponent(
                  mappingProps,
                  Component.props,
                  attrs,
                )}
                definitions={{
                  create_img: {
                    tip: '',
                    icon: 'image',
                    label: '',
                    handler: handleClickImgBtn,
                  },
                }}
                class={['t-editor', styles.module, focusedClass.value]}
                disable={mappingProps.disable || mappingProps.disabled}
                onUpdate:modelValue={onChange}
                modelValue={mappingProps.modelValue}
                onDoubleClick={onDoubleClickHandler}
                onClick={onClickHandler}
                // v-slots={{ ...slots }}
                dense={mappingProps.dense}
                toolbar={ toolbar.value}
                onBlur={onBlur}
                onFocus={onFocus}
                class={{ 'z-disabled': displayedErrorHint.value }}
                tabIndex={mappingProps.tabIndex}
                onPaste={mappingProps.pasteImage2Res && onPaste}
              >
                {{
                  token: () => (
                    <QButtonDropdown
                      class='s-focused'
                      ref={tokenRef}
                      no-caps
                      no-wrap
                      unelevated
                      flat
                      outline={false}
                      size='sm'
                      disable={mappingProps.disable || mappingProps.readonly}
                      text-color={mappingProps.toolbarTextColor}
                      menu-anchor='bottom end'
                      menu-self='top end'
                      icon='colorize'
                      tabIndex='-1'
                      onKeydown={withModifiers(handleColorBtnKeyDownDown, [
                        'ArrowDown',
                      ])}
                    >
                      <QList>
                        <QItem
                          tag='label'
                          clickable
                          onClick={setBackColor}
                          tabIndex='-1'
                        >
                          <QItemSection side>
                            <TIcon
                              color='var(--color-text-alpha-1)'
                              name='format_color_fill'
                            />
                          </QItemSection>
                          <QItemSection>
                            <colorSetPanel
                              modelValue={backColor.value}
                              onUpdate:modelValue={v => (backColor.value = v)}
                              palette={[
                                '#ffccccaa',
                                '#ffe6ccaa',
                                '#ffffccaa',
                                '#ccffccaa',
                                '#ccffe6aa',
                                '#ccffffaa',
                                '#cce6ffaa',
                                '#ccccffaa',
                                '#e6ccffaa',
                                '#ffccffaa',
                                '#ff0000aa',
                                '#ff8000aa',
                                '#ffff00aa',
                                '#00ff00aa',
                                '#00ff80aa',
                                '#00ffffaa',
                                '#0080ffaa',
                                '#0000ffaa',
                                '#8000ffaa',
                                '#ff00ffaa',
                                '#ffffffaa',
                                '#eeeeeeaa',
                                '#ddddddaa',
                                '#ccccccaa',
                                '#aaaaaaaa',
                                '#999999aa',
                                '#666666aa',
                                '#333333aa',
                                '#111111aa',
                                '#000000aa',
                              ]}
                              style='width: 180px;'
                            />
                          </QItemSection>
                        </QItem>

                        <QItem
                          tag='label'
                          clickable
                          onClick={setForeColor}
                          tabIndex='-1'
                        >
                          <QItemSection side>
                            <TIcon
                              color='var(--color-text-alpha-1)'
                              name='format_color_text'
                            />
                          </QItemSection>
                          <QItemSection>
                            <colorSetPanel
                              modelValue={foreColor.value}
                              onUpdate:modelValue={v => (foreColor.value = v)}
                              palette={[
                                '#ff0000',
                                '#ff8000',
                                '#ffff00',
                                '#00ff00',
                                '#00ff80',
                                '#00ffff',
                                '#0080ff',
                                '#0000ff',
                                '#8000ff',
                                '#ff00ff',
                                '#ffffff',
                                '#eeeeee',
                                '#dddddd',
                                '#cccccc',
                                '#aaaaaa',
                                '#999999',
                                '#666666',
                                '#333333',
                                '#111111',
                                '#000000',
                              ]}
                              style='width: 180px;'
                            />
                          </QItemSection>
                        </QItem>
                      </QList>
                    </QButtonDropdown>
                  ),
                }}

                {/* {slots} */}
              </Component>
              <TInnerLoading
                style='z-index: 120;color: var(--t-color);  opacity: 65%;'
                showing={isImg2ResLoading.value}
              />

              <imgSetPanel ref={imgSetPanelRef}></imgSetPanel>
            </div>

            {/*  必填校验显示  */}
            <div v-show={displayedErrorHint.value} class='u-error-message'>
              {errorHint.value}
            </div>
          </div>
        </div>
      );
    };
  },
});
